#ifndef NETWORK_PAT_H
#define NETWORK_PAT_H

#include "Message.h"
#include <vector>
#include <winsock2.h>

const int NUM_PARTS = 4;
const unsigned int HEADER_BYTES = 1113335557;
const unsigned int MAX_ADDRESS_LENGTH = 25;
const unsigned int WINNING_SCORE = 1500;
const int MAX_PLAYERS = 8;

enum NetMessage
{
  JOIN = 0,
  LEAVE,
  END,
  //message id is used as the number of players in the game for this message
  PLAYER_COUNT_UPDATE,
  //message id is used as the id of the player being assigned in this case
  ID_ASSIGNMENT,
  //message id is the random number seed for the players to use
  RANDOM_SEED,
  WIN,
  LOSE
};

class NetworkPat
{
  public:
    NetworkPat();
    ~NetworkPat();

    void Send(Message* msg);
    void SendToOne(Message* msg, int id);

    std::list<Message*>* Recv(void);

    void AddAddress(sockaddr_in addr);
    void RemoveAddress(int id);
    bool IsValid(void);

    //getters and setters for all those hacks... :(
    // ya know, when I think about it, I guess this means my Network Engine networks in
    // 2 senses of the word, since it also networks info between game states
    // much of this stuff should have been added to the game class
    // but since controllers/models/views don't know about the game, I couldn't just
    // keep it there
    void SetId(int id);
    int GetId(void);
    void SetCount(int count);
    int GetCount(void);
    void SetSeed(int seed);
    int GetSeed(void);
    void Reset(void);
    char* GetAddr(void);
	  unsigned short GetPort(void);
    unsigned int GetAddrCount(void);

    //for score keeping, returns the new score
    int IncrementLocalScore(int inc);
    void SetWin(bool win);
    bool GetWin(void);
  private:
    bool Init(void);
    void Cleanup(void);
    bool ErrorCheck(const char* message);
    //msg is an input, length is an output
    char* Serialize(Message* msg, int* length);
    Message* Deserialize(char* buffer, int length);

    std::vector<sockaddr_in> mClients;
    WSADATA mData;
    SOCKET mSocket;
    sockaddr_in mLocal;
    bool mSuccess;

    int mSizeArray[NUM_PARTS];
    int mTotalSize;

    //this is game specific data that is given by the server to a player
    // the server's id is 0
    // at the start of a game, players create all ships, then they use their id to
    //  identify themselves and sign their packets
    // the server does maintain the player count, as do all players
    //many of these data elements are hacks for the sake of getting information passed appropriately between game states
    int mLocalId; //player id from server
    int mPlayerCount; //players in game
    int mRandSeed; //random number seed for determinism
    char mRecvAddr[MAX_ADDRESS_LENGTH]; //address I'm receiving on (server)
    int mLocalScore; //score I have 
    bool mWin; //I won?
  	unsigned short mPort; //port I'm listening on (server)

    std::list<Message*> msgList; //list of network messages
};

#endif
